﻿using Datav.Design.Common;
using Datav.Design.IService;
using Zdap.Common;
using Zdap.Common.Extensions;
using Zdap.XCode.Service;

namespace Datav.Design.Service
{
    /// <summary>
    ///
    /// </summary>
    public class QuestionCategoryService : BaseService<QuestionCategory, QuestionCategoryModel>, IQuestionCategoryService
    {
        /// <summary>
        /// 设置分库表
        /// </summary>
        /// <param name="ProjectId"></param>
        private static void SetQuestionCategoryPolicy(long ProjectId)
        {
            //var connName = $"{QuestionCategory.Meta.ConnName}_{ProjectId}";
            //QuestionCategory.Meta.ConnName = connName;
            var tableName = $"{QuestionCategory.Meta.TableName}_{ProjectId}";
            QuestionCategory.Meta.TableName = tableName;
            //QuestionCategory.Meta.Session.Dal.DbType = DatabaseType.MySql;
            //QuestionCategory.Meta.Session.Dal.ConnName
            //QuestionCategory.Meta.ConnName = connName;

            //var db = $"Data Source =.; Port=3306; User ID = root; Password = zd123456; Initial Catalog = {connName}; charset = utf8; SslMode = none; Max pool size = 200";
            //DAL.AddConnStr(connName, db, null, "MySql");
            //var ta = DAL.Create(connName);
            //ta.Db.CreateSession();
            //ta.CheckDatabase();
            //ta.CheckTables();
            ////ta.Tables;
            //var student = new QuestionCategory() { Id = IdWorker.NextId() };
            //// Name =“大石头”ClassID = 123,Sex = SexKinds.男，Age = 35
            //student.Insert();
            //   var st = Student.FindByID(1)Console.WriteLine(st.ToJson(true))
        }

        /// <summary>
        /// 设置分库表
        /// </summary>
        /// <param name="ProjectId"></param>
        private static void SetQuestionPolicy(long ProjectId)
        {
            // var connName = $"{Question.Meta.ConnName}_{ProjectId}";
            //Question.Meta.ConnName = connName;
            var tableName = $"{Question.Meta.ConnName}_{ProjectId}";
            QuestionCategory.Meta.TableName = tableName;
        }

        /// <summary>
        /// 保存
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public override async ValueTask<ResponseContext<long>> Save(QuestionCategoryModel dto, UserTicket user)
        {
            var data = await base.Save(dto, user);
            return data;
        }

        /// <summary>
        /// 查询树结构
        /// </summary>
        /// <param name="ProjectId"></param>
        /// <param name="configId"></param>
        /// <returns></returns>
        public async Task<ListResponseContext<QuestionCategoryTreeModel>> QuestionCategoryTree(long ProjectId, long configId)
        {
            //SetQuestionCategoryPolicy(ProjectId);
            var result = new ListResponseContext<QuestionCategoryTreeModel>();
            var where = new Dictionary<string, object>
            {
                [QuestionCategory._.ProjectId] = ProjectId,
                [QuestionCategory._.ConfigId] = configId,
                ["OrderBy"] = "Sort asc "
            };

            var r_entities = await CommonService.SearchAll<QuestionCategory, QuestionCategoryTreeModel>(where);
            if (r_entities.IsNullOrEmpty())
                return result;

            var r = TreeBase.CreateTree(r_entities);

            return result.SetSuccess(r);
        }

        /// <summary>
        /// 查询树结构
        /// </summary>
        /// <param name="ProjectId"></param>
        /// <param name="configId"></param>
        /// <returns></returns>
        public async Task<ListResponseContext<QuestionCategoryTreeModel>> TreeCategoryQuestion(long ProjectId, long configId)
        {
            //SetQuestionCategoryPolicy(ProjectId);
            var result = new ListResponseContext<QuestionCategoryTreeModel>();
            var where = new Dictionary<string, object>
            {
                [QuestionCategory._.ProjectId] = ProjectId,
                [QuestionCategory._.ConfigId] = configId,
                ["OrderBy"] = "Sort asc"
            };

            var r_entities = await CommonService.SearchAll<QuestionCategory, QuestionCategoryTreeModel>(where);
            if (r_entities.IsNullOrEmpty())
                return result;
            if (r_entities.Any())
            {
                where = new Dictionary<string, object>
                {
                    [Question._.ProjectId] = ProjectId,
                    [Question._.ConfigId] = configId,
                    [Question._.QuestionCategoryId] = r_entities.Select(s => s.Id).ToArray(),
                    [Question._.Status] = (int)QEnum.Started,
                    ["OrderBy"] = "Sort asc"
                };
                //where.Add($"{Question._.QuestionCategoryId}",);
                //where.Add($"{Question._.Status}", );
                var questions = await CommonService.SearchAll<Question, QuestionTreeModel>(where);
                questions.OrderBy(s => s.Sort).ForEach(s =>
                {
                    var item = new QuestionCategoryTreeModel();
                    item.ParentId = s.QuestionCategoryId;
                    item.Id = s.Id;
                    item.IsQuestion = true;
                    item.Sort = s.Sort;
                    item.Name = s.Title;
                    r_entities.Add(item);
                });
            }

            var r = TreeBase.CreateTree(r_entities);

            return result.SetSuccess(r);
        }

        /// <summary>
        /// 添加对象参数校验
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        protected override async ValueTask<ResponseContext<bool>> AddValidate(QuestionCategoryModel dto)
        {
            // SetQuestionCategoryPolicy(dto.ProjectId);
            var result = new ResponseContext<bool>();
            if (string.IsNullOrWhiteSpace(dto.Name))
            {
                return result.SetError($"分类名称不能为空！");
            }
            var where = QuestionCategory._.ProjectId == dto.ProjectId & QuestionCategory._.ParentId == dto.ParentId & QuestionCategory._.Name == dto.Name & QuestionCategory._.IsDelete == 0;
            var entity = await CommonService.FindBy<QuestionCategory>(where);
            if (entity != null)
            {
                return result.SetError($"分类名称“{dto.Name}”已存在，不能重复！");
            }

            return result.SetSuccess(true);
        }

        /// <summary>
        /// 修改对象参数校验
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        protected override async ValueTask<ResponseContext<bool>> UpdateValidate(QuestionCategoryModel dto)
        {
            //SetQuestionCategoryPolicy(dto.ProjectId);
            var result = new ResponseContext<bool>();
            if (string.IsNullOrWhiteSpace(dto.Name))
            {
                return result.SetError($"名称不能为空！");
            }
            var where = QuestionCategory._.ProjectId == dto.ProjectId & QuestionCategory._.ParentId == dto.ParentId & QuestionCategory._.Name == dto.Name & QuestionCategory._.IsDelete == 0;
            if (dto.Id > 0)
            {
                where &= QuestionCategory._.Id != dto.Id;
            }
            var entity = await CommonService.FindBy<QuestionCategory>(where);
            if (entity != null)
            {
                return result.SetError($"名称“{dto.Name}”已存在，不能重复！");
            }
            return result.SetSuccess(true);
        }

        /// <summary>
        /// 判断是否存在
        /// </summary>
        /// <param name="id"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public override async ValueTask<ResponseContext<bool>> Delete(long id, UserTicket user)
        {
            var entity = await this.FindById(id);

            if (await IsExistQuestion(id, entity.Data.ProjectId))
            {
                return new ResponseContext<bool>(400, "当前下有子分类题目，当前不可删除");
            }
            return await base.Delete(id, user);
        }

        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="rootQuestionCategoryId"></param>
        /// <param name="ProjectId"></param>
        /// <returns></returns>
        private async Task<bool> IsExistQuestion(long rootQuestionCategoryId, long ProjectId)
        {
            //SetQuestionPolicy(ProjectId);
            var questionCategoryIds = await GetDescendantQuestionCategoryIdList(rootQuestionCategoryId, ProjectId);
            if (questionCategoryIds.Any())
            {
                var count = await Question.FindCountAsync(Question._.QuestionCategoryId.In(questionCategoryIds) & Question._.IsDelete == 0);
                return count > 0;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 获取子孙分类Id
        /// </summary>
        /// <param name="questionCategoryId"></param>
        /// <param name="ProjectId"></param>
        /// <returns></returns>
        private async Task<List<long>> GetDescendantQuestionCategoryIdList(long questionCategoryId, long ProjectId)
        {
            //SetQuestionPolicy(ProjectId);
            //SetQuestionCategoryPolicy(ProjectId);
            var ids = new List<long> { questionCategoryId };
            var childQuestionCategoryList = await QuestionCategory.FindAllAsync(QuestionCategory._.ParentId == questionCategoryId & QuestionCategory._.IsDelete == 0);
            if (childQuestionCategoryList.Any())
            {
                foreach (var childQuestionCategory in childQuestionCategoryList)
                {
                    ids.AddRange(await GetDescendantQuestionCategoryIdList(childQuestionCategory.Id, ProjectId));
                }
            }
            return ids;
        }
    }
}